package model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.commons.lang3.SystemUtils;

/**
 * This class controlls the application settings of the system.
 * 
 * @author Brayan Zimmerli
 * 
 */
public class ApplicationSettingsPersistence {

	private static String sp = SystemUtils.FILE_SEPARATOR;

	/**
	 * Returns the application's preference file. Use this file to store all application specific files.
	 * @return Properties The property file to store all application settings.
	 * @throws SecurityException
	 * @throws IOException
	 */
	public static Properties getApplicationPropertyFile() throws SecurityException, IOException {
		final String PREFERENCE_FILE = "preferences.properties";
		Properties prop = new Properties();
		File prefFile = null;
		try {
			prefFile = new File(getAppDataDirectory().getAbsoluteFile() + sp + PREFERENCE_FILE);
			if (!prefFile.exists())
				prefFile.createNewFile();
		} catch (IOException ioe) {
			throw new IOException("Failed to create the applications preference file at "
					+ prefFile.getPath() + ". " + ioe.getMessage());
		} catch (SecurityException se) {
			throw new SecurityException("Failed to retrieve the applications preference file from "
					+ prefFile.getPath() + ". " + se.getMessage());
		}

		FileInputStream fileInput;
		try {
			fileInput = new FileInputStream(prefFile);
		} catch (FileNotFoundException e) {
			// TODO use Logger
			throw new FileNotFoundException(
					"Failed to retrieve preference file as file input stream. " + e.getMessage());
		}
		prop.load(fileInput);
		
		return prop;
	}

	/**
	 * Returns the operating specific data directory. This is the users data
	 * directory plus the application path.
	 * 
	 * @return File The directory Path of the application Settings.
	 */
	private static File getAppDataDirectory() throws SecurityException {
		String sp = SystemUtils.FILE_SEPARATOR;
		String appDirString = "Melinxa";
		File appDir = null;

		if (SystemUtils.IS_OS_WINDOWS)
			appDir = enforceDirectory(System.getenv("APPDATA") + sp + appDirString);
		else if (SystemUtils.IS_OS_MAC)
			appDir = enforceDirectory(System.getProperty("user.home") + sp + "Library" + sp
					+ "Application Support" + sp + appDirString);
		else if (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_UNIX)
			// On linux, put it in a hidden directory it common habit.
			appDir = enforceDirectory(System.getProperty("user.home") + sp + "." + appDirString);
		else
			appDir = enforceDirectory(System.getProperty("user.home") + sp + "." + appDirString);

		return appDir;
	}

	/**
	 * Make sure the application data folder exists.
	 */
	private static File enforceDirectory(String path) throws SecurityException {
		File dir = new File(path);

		try {
			if (!dir.exists()) {
				// TODO use logger
				System.out.println("Create new application data path: " + dir.getPath());
				dir.mkdirs();
			}
		} catch (SecurityException se) {
			throw new SecurityException(
					"Failed to create a new application directory due to security exceptions.");
		}

		return dir;
	}
}
